void
_gtk_print_operation_platform_backend_launch_preview (GtkPrintOperation *op,
+ cairo_surface_t *surface,
GtkWindow *parent,
const gchar *filename)
{
gchar *quoted_filename;
GdkScreen *screen;
GError *error = NULL;
+
+ cairo_surface_destroy (pop->surface);
settings = gtk_settings_get_default ();
g_object_get (settings, "gtk-print-preview-command", &preview_cmd, NULL);
GtkPageSetup *page_setup,
gdouble *dpi_x,
gdouble *dpi_y,
- const gchar *target)
+ gchar **target)
{
+ gchar *tmp_dir, *dir_template, *preview_filename;
GtkPaperSize *paper_size;
gdouble w, h;
+ dir_template = g_build_filename (g_get_tmp_dir (), "print-preview-XXXXXX", NULL);
+
+ /* use temp dirs because apps like evince need to have extensions
+ * to determine the mime type
+ */
+ tmp_dir = mkdtemp(dir_template);
+ preview_filename = g_build_filename (tmp_dir,
+ "Print Preview.pdf",
+ NULL);
+ g_free (dir_template);
+ *target = preview_filename;
+
paper_size = gtk_page_setup_get_paper_size (page_setup);
w = gtk_paper_size_get_width (paper_size, GTK_UNIT_POINTS);
h = gtk_paper_size_get_height (paper_size, GTK_UNIT_POINTS);
*dpi_x = *dpi_y = 72;
- return cairo_pdf_surface_create (target, w, h);
+ return cairo_pdf_surface_create (preview_filename, w, h);
+}
+
+void
+_gtk_print_operation_platform_backend_preview_start_page (GtkPrintOperation *op,
+ cairo_surface_t *surface,
+ cairo_t *cr)
+{
+}
+
+void
+_gtk_print_operation_platform_backend_preview_end_page (GtkPrintOperation *op,
+ cairo_surface_t *surface,
+ cairo_t *cr)
+{
+ cairo_show_page (cr);
}
void
#define COBJMACROS
#include "config.h"
#include <math.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <stdio.h>
#include <stdlib.h>
#include <cairo-win32.h>
#include <glib.h>
int job_id;
guint timeout_id;
+ cairo_surface_t *surface;
GtkWidget *embed_widget;
} GtkPrintOperationWin32;
GlobalFree(op_win32->devmode);
GlobalFree(op_win32->devnames);
- cairo_surface_finish (op->priv->surface);
- cairo_surface_destroy (op->priv->surface);
- op->priv->surface = NULL;
+ cairo_surface_finish (op_win32->surface);
+ cairo_surface_destroy (op_win32->surface);
+ op_win32->surface = NULL;
DeleteDC(op_win32->hdc);
return hpage;
}
+static GtkPageSetup *
+create_page_setup (GtkPrintOperation *op)
+{
+ GtkPrintOperationPrivate *priv = op->priv;
+ GtkPageSetup *page_setup;
+ GtkPrintSettings *settings;
+
+ if (priv->default_page_setup)
+ page_setup = gtk_page_setup_copy (priv->default_page_setup);
+ else
+ page_setup = gtk_page_setup_new ();
+
+ settings = priv->print_settings;
+ if (settings)
+ {
+ GtkPaperSize *paper_size;
+
+ if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_ORIENTATION))
+ gtk_page_setup_set_orientation (page_setup,
+ gtk_print_settings_get_orientation (settings));
+
+
+ paper_size = gtk_print_settings_get_paper_size (settings);
+ if (paper_size)
+ {
+ gtk_page_setup_set_paper_size (page_setup, paper_size);
+ gtk_paper_size_free (paper_size);
+ }
+
+ /* TODO: Margins? */
+ }
+
+ return page_setup;
+}
+
GtkPrintOperationResult
_gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op,
+ gboolean show_dialog,
GtkWindow *parent,
- gboolean *do_print,
- GError **error)
+ gboolean *do_print)
{
HRESULT hResult;
LPPRINTDLGEXW printdlgex = NULL;
GtkWidget *invisible = NULL;
GtkPrintOperationResult result;
GtkPrintOperationWin32 *op_win32;
+ GtkPrintOperationPrivate *priv;
IPrintDialogCallback *callback;
HPROPSHEETPAGE prop_page;
*do_print = FALSE;
+ priv = op->priv;
+
op_win32 = g_new0 (GtkPrintOperationWin32, 1);
- op->priv->platform_data = op_win32;
- op->priv->free_platform_data = (GDestroyNotify) op_win32_free;
+ priv->platform_data = op_win32;
+ priv->free_platform_data = (GDestroyNotify) op_win32_free;
if (parent == NULL)
{
if (!printdlgex)
{
result = GTK_PRINT_OPERATION_RESULT_ERROR;
- g_set_error (error,
+ g_set_error (&priv->error,
GTK_PRINT_ERROR,
GTK_PRINT_ERROR_NOMEM,
_("Not enough free memory"));
if (!page_ranges)
{
result = GTK_PRINT_OPERATION_RESULT_ERROR;
- g_set_error (error,
+ g_set_error (&priv->error,
GTK_PRINT_ERROR,
GTK_PRINT_ERROR_NOMEM,
_("Not enough free memory"));
{
result = GTK_PRINT_OPERATION_RESULT_ERROR;
if (hResult == E_OUTOFMEMORY)
- g_set_error (error,
+ g_set_error (&priv->error,
GTK_PRINT_ERROR,
GTK_PRINT_ERROR_NOMEM,
_("Not enough free memory"));
else if (hResult == E_INVALIDARG)
- g_set_error (error,
+ g_set_error (&priv->error,
GTK_PRINT_ERROR,
GTK_PRINT_ERROR_INTERNAL_ERROR,
_("Invalid argument to PrintDlgEx"));
else if (hResult == E_POINTER)
- g_set_error (error,
+ g_set_error (&priv->error,
GTK_PRINT_ERROR,
GTK_PRINT_ERROR_INTERNAL_ERROR,
_("Invalid pointer to PrintDlgEx"));
else if (hResult == E_HANDLE)
- g_set_error (error,
+ g_set_error (&priv->error,
GTK_PRINT_ERROR,
GTK_PRINT_ERROR_INTERNAL_ERROR,
_("Invalid handle to PrintDlgEx"));
else /* E_FAIL */
- g_set_error (error,
+ g_set_error (&priv->error,
GTK_PRINT_ERROR,
GTK_PRINT_ERROR_GENERAL,
_("Unspecified error"));
{
DOCINFOW docinfo;
int job_id;
-
+ double dpi_x, dpi_y;
+ cairo_t *cr;
+ GtkPageSetup *page_setup;
+
+ priv->print_context = _gtk_print_context_new (op);
+ page_setup = create_page_setup (op);
+ _gtk_print_context_set_page_setup (priv->print_context, page_setup);
+ g_object_unref (page_setup);
+
*do_print = TRUE;
- op->priv->surface = cairo_win32_surface_create (printdlgex->hDC);
- op->priv->dpi_x = (double)GetDeviceCaps (printdlgex->hDC, LOGPIXELSX);
- op->priv->dpi_y = (double)GetDeviceCaps (printdlgex->hDC, LOGPIXELSY);
+ op_win32->surface = cairo_win32_surface_create (printdlgex->hDC);
+ dpi_x = (double)GetDeviceCaps (printdlgex->hDC, LOGPIXELSX);
+ dpi_y = (double)GetDeviceCaps (printdlgex->hDC, LOGPIXELSY);
+ cr = cairo_create (op_win32->surface);
+ gtk_print_context_set_cairo_context (priv->print_context, cr, dpi_x, dpi_y);
+ cairo_destroy (cr);
+
memset( &docinfo, 0, sizeof (DOCINFOW));
docinfo.cbSize = sizeof (DOCINFOW);
docinfo.lpszDocName = g_utf8_to_utf16 (op->priv->job_name, -1, NULL, NULL, NULL);
if (job_id <= 0)
{
result = GTK_PRINT_OPERATION_RESULT_ERROR;
- g_set_error (error,
+ g_set_error (&priv->error,
GTK_PRINT_ERROR,
GTK_PRINT_ERROR_GENERAL,
_("Error from StartDoc"));
*do_print = FALSE;
- cairo_surface_destroy (op->priv->surface);
- op->priv->surface = NULL;
+ cairo_surface_destroy (op_win32->surface);
+ op_win32->surface = NULL;
goto out;
}
return result;
}
-void
-_gtk_print_operation_platform_backend_run_dialog_async (GtkPrintOperation *op,
- GtkWindow *parent,
- GtkPrintOperationPrintFunc print_cb)
+void
+_gtk_print_operation_platform_backend_launch_preview (GtkPrintOperation *op,
+ cairo_surface_t *surface,
+ GtkWindow *parent,
+ const gchar *filename)
{
- gboolean do_print;
+ HDC dc;
+ HENHMETAFILE metafile;
+
+ dc = cairo_win32_surface_get_dc (surface);
+ cairo_surface_destroy (surface);
+ metafile = CloseEnhMetaFile (dc);
+ DeleteEnhMetaFile (metafile);
+
+ ShellExecuteW (NULL, L"open", (gunichar2 *)filename, NULL, NULL, SW_SHOW);
+}
- _gtk_print_operation_platform_backend_run_dialog (op, parent, &do_print, NULL);
- if (do_print)
- print_cb (op, parent, FALSE);
- else
- _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED_ABORTED, NULL);
+void
+_gtk_print_operation_platform_backend_preview_start_page (GtkPrintOperation *op,
+ cairo_surface_t *surface,
+ cairo_t *cr)
+{
+ HDC dc = cairo_win32_surface_get_dc (surface);
+ StartPage (dc);
+}
+
+void
+_gtk_print_operation_platform_backend_preview_end_page (GtkPrintOperation *op,
+ cairo_surface_t *surface,
+ cairo_t *cr)
+{
+ /* TODO: This doesn't actually seem to work.
+ * Do enhanced metafiles really support multiple pages?
+ */
+ HDC dc = cairo_win32_surface_get_dc (surface);
+ EndPage (dc);
+}
+
+cairo_surface_t *
+_gtk_print_operation_platform_backend_create_preview_surface (GtkPrintOperation *op,
+ GtkPageSetup *page_setup,
+ gdouble *dpi_x,
+ gdouble *dpi_y,
+ gchar **target)
+{
+ GtkPaperSize *paper_size;
+ double w, h;
+ HDC metafile_dc;
+ RECT rect;
+ char *template;
+ char *filename;
+ gunichar2 *filename_utf16;
+ int fd;
+
+ template = g_build_filename (g_get_tmp_dir (), "prXXXXXX", NULL);
+ fd = g_mkstemp (template);
+ close(fd);
+
+ filename = g_strconcat (template, ".emf", NULL);
+ g_free (template);
+
+ filename_utf16 = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+ g_free (filename);
+
+ paper_size = gtk_page_setup_get_paper_size (page_setup);
+ w = gtk_paper_size_get_width (paper_size, GTK_UNIT_MM);
+ h = gtk_paper_size_get_height (paper_size, GTK_UNIT_MM);
+
+ rect.left = 0;
+ rect.right = w*100;
+ rect.top = 0;
+ rect.bottom = h*100;
+
+ metafile_dc = CreateEnhMetaFileW (NULL, filename_utf16,
+ &rect, L"Gtk+\0Print Preview\0\0");
+ if (metafile_dc == NULL)
+ {
+ g_warning ("Can't create metafile");
+ return NULL;
+ }
+
+ *target = (char *)filename_utf16;
+
+ *dpi_x = (double)GetDeviceCaps (metafile_dc, LOGPIXELSX);
+ *dpi_y = (double)GetDeviceCaps (metafile_dc, LOGPIXELSY);
+
+ return cairo_win32_surface_create (metafile_dc);
+}
+
+void
+_gtk_print_operation_platform_backend_resize_preview_surface (GtkPrintOperation *op,
+ GtkPageSetup *page_setup,
+ cairo_surface_t *surface)
+{
+ /* TODO: Implement */
}
GtkPageSetup *
op = GTK_PRINT_OPERATION (pop->preview);
+ cairo_surface_finish (pop->surface);
+ /* Surface is destroyed in launch_preview */
_gtk_print_operation_platform_backend_launch_preview (op,
+ pop->surface,
pop->parent,
pop->filename);
g_free (pop->filename);
- cairo_surface_finish (pop->surface);
- cairo_surface_destroy (pop->surface);
gtk_print_operation_preview_end_preview (pop->preview);
g_free (pop);
gtk_print_operation_preview_render_page (pop->preview, pop->page_nr);
cr = gtk_print_context_get_cairo_context (pop->print_context);
- cairo_show_page (cr);
+ _gtk_print_operation_platform_backend_preview_end_page (op, pop->surface,
+ cr);
/* TODO: print out sheets not pages and follow ranges */
pop->page_nr++;
PreviewOp *pop)
{
GtkPrintOperation *op = GTK_PRINT_OPERATION (preview);
+ cairo_t *cr;
_gtk_print_operation_platform_backend_resize_preview_surface (op, page_setup, pop->surface);
+
+ cr = gtk_print_context_get_cairo_context (pop->print_context);
+ _gtk_print_operation_platform_backend_preview_start_page (op, pop->surface,
+ cr);
+
}
static void
GtkWindow *parent)
{
gdouble dpi_x, dpi_y;
- gchar *tmp_dir;
- gchar *dir_template;
- gchar *preview_filename;
PreviewOp *pop;
GtkPageSetup *page_setup;
cairo_t *cr;
- dir_template = g_build_filename (g_get_tmp_dir (), "print-preview-XXXXXX", NULL);
-
- /* use temp dirs because apps like evince need to have extensions
- * to determine the mime type
- */
- tmp_dir = mkdtemp(dir_template);
-
- preview_filename = g_build_filename (tmp_dir,
- "Print Preview.pdf",
- NULL);
-
- g_free (dir_template);
-
pop = g_new0 (PreviewOp, 1);
- pop->filename = preview_filename;
+ pop->filename = NULL;
pop->preview = preview;
pop->parent = parent;
_gtk_print_operation_platform_backend_create_preview_surface (op,
page_setup,
&dpi_x, &dpi_y,
- pop->filename);
+ &pop->filename);
cr = cairo_create (pop->surface);
gtk_print_context_set_cairo_context (op->priv->print_context, cr,
priv->is_sync = !priv->allow_async;
}
+#ifndef G_OS_WIN32
else if (priv->allow_async)
{
priv->is_sync = FALSE;
print_pages);
result = GTK_PRINT_OPERATION_RESULT_IN_PROGRESS;
}
+#endif
else
{
priv->is_sync = TRUE;